package cn.lxg.utils;

import cn.hutool.core.collection.CollectionUtil;

import java.util.*;

public class RangeUtil {

    public static Map<Integer, Integer> highFreqRange( Map<Integer, Integer> frequencyMap){

        // 步骤1：获取出现次数的所有值（出现次数）
        Collection<Integer> frequencies = frequencyMap.values();


        // 可选：如果你希望使用四分位数来定义高频范围，可以使用以下代码：
        List<Integer> freqList = new ArrayList<>(frequencies);
        Collections.sort(freqList);
        int q75Index = (int) Math.floor(0.75 * (freqList.size() - 1));  // 75th percentile index
        int q75 = freqList.get(q75Index);

        Map<Integer, Integer> highFreqRangeByQ = new HashMap<>();
        for (Map.Entry<Integer, Integer> entry : frequencyMap.entrySet()) {
            if (entry.getValue() >= q75) {
                highFreqRangeByQ.put(entry.getKey(), entry.getValue());
            }
        }


        return highFreqRangeByQ;
    }

    /**
     * 计算出范围
     *
     * @param array
     * @return
     */
    public static List<Integer> getMostFrequentNumberRange(List<Integer> array) {
        if (CollectionUtil.isEmpty(array)) {
            return null;
        }

        // 使用 HashMap 来记录每个数字的出现频率
        Map<Integer, Integer> frequencyMap = new HashMap<>();

        for (int num : array) {
            frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1);
        }
        Map<Integer, Integer> map = highFreqRange(frequencyMap);
        Set<Integer> set = map.keySet();
        Integer max = CollectionUtil.max(set);
        Integer min = CollectionUtil.min(set);
        List<Integer> result = new ArrayList<>();
        result.add(min);
        result.add(max);
        return result;
    }

    /**
     * 出现连续数的次数
     * @param numbers
     * @return
     */
    public static int getConsecutiveGroupsCountNum(List<Integer> numbers) {
        // 将集合转为列表并排序
        List<Integer> sortedList = new ArrayList<>(numbers);
        Collections.sort(sortedList);

        int count = 0;
        int groupSize = 1;  // 每组的数字至少有一个
        for (int i = 1; i < sortedList.size(); i++) {
            // 判断当前数字和前一个数字是否连续
            if (sortedList.get(i) == sortedList.get(i - 1) + 1) {
                groupSize++;
            } else {
                // 如果不是连续的，则说明一个新的序列开始
                if (groupSize > 1) {
                    count++;
                }
                groupSize = 1;
            }
        }

        // 如果最后一组连续数字大于1个，计入
        if (groupSize > 1) {
            count++;
        }

        return count+1;
    }

    /**
     * 连续次数
     *
     * @param numbers
     * @return
     */
    public static Integer getConsecutiveGroupsCount(List<Integer> numbers) {
        // 将集合转为列表并排序
        List<Integer> sortedList = new ArrayList<>(numbers);
        Collections.sort(sortedList);

        List<Integer> resultList = new ArrayList<>();
        int groupSize = 1;  // 每组的数字至少有一个
        for (int i = 1; i < sortedList.size(); i++) {
            // 判断当前数字和前一个数字是否连续
            if (sortedList.get(i) == sortedList.get(i - 1) + 1) {
                groupSize++;
            } else {
                // 如果不是连续的，则说明一个新的序列开始
                if (groupSize > 1) {
                    resultList.add(groupSize);
                }
                groupSize = 1;
            }
        }
        if (groupSize>1) {
            resultList.add(groupSize);
        }
        return CollectionUtil.isEmpty(resultList) ? 0 : CollectionUtil.max(resultList);
    }

    /**
     * 判断两个集合相同的有多少个
     *
     * @param list1
     * @param list2
     * @return
     */
    public static int getCommonElementsCount(List<Integer> list1, List<Integer> list2) {
        // 将第一个数组转换为 Set 集合
        Set<Integer> set1 = new HashSet<>(list1);

        // 遍历第二个数组，检查每个元素是否在 set1 中
        int count = 0;
        for (int num : list2) {
            if (set1.contains(num)) {
                count++;
                set1.remove(num);  // 这样可以避免重复计数
            }
        }
        return count;
    }

    // 找到集合中最接近目标值的数字
    public static int findClosestValue(List<Integer> collection, int target) {
        if (collection == null || collection.isEmpty()) {
           return 0;
        }

        int closest = collection.get(0); // 初始化最接近值为集合中的第一个元素
        int minDiff = Math.abs(target - closest); // 初始化最小差值

        // 遍历集合中的每个元素
        for (int num : collection) {
            int diff = Math.abs(target - num); // 计算当前元素与目标值的差值
            if (diff == 0) {
                continue;
            }
            if (diff < minDiff) {
                minDiff = diff;
                closest = num; // 更新最接近的数字
            }
        }

        return closest;
    }
}
